package cn.jimmie.learn.viewArt.ball;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.util.TypedValue;
import android.view.View;
import android.view.WindowManager;

import cn.jimmie.learn.viewArt.R;


/**
 * function : 悬浮球回收 视图
 * 由于 该视图是添加到 WindowManager中, 因此无需使用 xml形式的布局方式
 *
 * <p> Create Time: 2018年12月31日 09:17 </p>
 * <p> @author Jimmie.Qian  </p>
 */
@SuppressLint("ViewConstructor")
class AssistGCView extends View implements OnScreenChangedObserver {
    private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
    // 各样式和资源的控制
    private final Conf conf;
    private final WindowManager.LayoutParams layoutParams;
    private final WindowManager windowManager;
    private final RectF recf = new RectF();
    // 屏幕宽高, 屏幕变化时将更新
    private int W, H;
    // 是否命中
    private boolean isHit;
    // 是否添加到window
    private boolean isAttached;

    private AssistGCView(Context context, Conf conf) {
        super(context);
        this.conf = conf;

        layoutParams = LayoutParamUtils.createLayoutParams(context);
        // 设置不拦截任何触摸事件
        layoutParams.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
        windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        W = windowManager.getDefaultDisplay().getWidth();
        H = windowManager.getDefaultDisplay().getHeight();

        paint.setTextAlign(Paint.Align.CENTER);
        paint.setTextSize(conf.DIMEN.tS);
    }

    public static Builder creator(Context context) {
        return new Builder(context);
    }

    /**
     * 添加window,并且更新位置
     */
    public void attachToWindow() {
        attachToWindow(false);
    }

    private void attachToWindow(boolean requestLayout) {
        if (isAttached && !requestLayout) return;
        layoutParams.x = 0;
        layoutParams.y = H - conf.DIMEN.height - conf.DIMEN.paddingBottom;
        if (!isAttached) {
            isAttached = true;
            windowManager.addView(this, layoutParams);
        } else {
            windowManager.updateViewLayout(this, layoutParams);
        }
    }

    /**
     * 从window中移除
     */
    public void detachFromWindow() {
        if (isAttached) {
            isAttached = false;
            windowManager.removeViewImmediate(this);
        }
    }

    /**
     * 传入悬浮球左上角位置, 检查是否进入了 GC 区域
     */
    public void checkHit(int x, int y) {
        boolean hit = (x > W / 4 && x < W * 3 / 4)
            && y > (H - getHeight() - conf.DIMEN.paddingBottom * 4);
        if (hit != isHit) {
            isHit = hit;
            invalidate();
        }
    }

    public boolean isHit() {
        return isHit;
    }

    @Override
    public void onLayoutChanged(int width, int height) {
        W = width;
        H = height;
        if (isAttached) {
            attachToWindow(true);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        paint.setColor(Color.BLACK);
        paint.setAlpha(80);

        float radius = conf.DIMEN.height >> 1;
        float w = conf.DIMEN.width;
        recf.set((getWidth() - w) / 2, 0, (getWidth() + w) / 2, getHeight());
        canvas.drawRoundRect(recf, radius, radius, paint);

        // 文字 和 icon
        paint.setAlpha(255);
        Paint.FontMetrics fm = paint.getFontMetrics();
        int y = getHeight() / 2;

        int size = conf.DIMEN.tS;
        int baseY = (int) (y - (fm.descent + fm.ascent) / 2);
        int top = y - size / 2;
        int bottom = y + size / 2;

        Drawable drawable = isHit ? conf.RES.hitDelDw : conf.RES.normalDelDw;
        String text = isHit ? conf.RES.hitTx : conf.RES.normalTx;
        int color = isHit ? conf.COLOR.hit : conf.COLOR.normal;

        paint.setColor(color);
        // draw text
        canvas.drawText(text, (getWidth() + size) >> 1, baseY, paint);

        // draw icon
        int right = getWidth() / 2 - (int) paint.measureText(text) / 2;
        drawable.setBounds(right - size, top, right, bottom);
        drawable.draw(canvas);
    }

    /**
     * 自己测量宽高, 使得 WindowManger.LayoutParams 的 width,height 属性失效
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int mode = MeasureSpec.getMode(widthMeasureSpec);
        super.onMeasure(MeasureSpec.makeMeasureSpec(W, mode), MeasureSpec.makeMeasureSpec(conf.DIMEN.height, mode));
    }

    // ================== config ====================

    public static class Builder {
        private final Context ctx;
        private final Conf conf;

        private Builder(Context ctx) {
            this.ctx = ctx;
            conf = new Conf();
            init();
        }

        private void init() {
            float dp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                1, ctx.getResources().getDisplayMetrics());
            float sp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                1, ctx.getResources().getDisplayMetrics());

            conf.COLOR.normal = Color.WHITE;
            conf.COLOR.hit = Color.parseColor("#ff9515");
            conf.DIMEN.height = (int) (50 * dp);
            conf.DIMEN.width = (int) (300 * dp);
            conf.DIMEN.paddingBottom = (int) (10 * dp);
            conf.DIMEN.tS = (int) (13 * sp);
            conf.RES.normalTx = ctx.getResources().getString(R.string.m4399_ope_assist_gc_normal);
            conf.RES.hitTx = ctx.getResources().getString(R.string.m4399_ope_assist_gc_hit);
            conf.RES.normalDelDw = ContextCompat.getDrawable(ctx, R.drawable.m4399_ope_assist_pop_delete);
            conf.RES.hitDelDw = ContextCompat.getDrawable(ctx, R.drawable.m4399_ope_assist_pop_delete_hit);
        }

        public AssistGCView create() {
            return new AssistGCView(ctx, conf);
        }
    }

    private static class Conf {
        final Color COLOR;
        final Dimen DIMEN;
        final Res RES;

        Conf() {
            COLOR = new Color();
            DIMEN = new Dimen();
            RES = new Res();
        }

        // 颜色
        class Color {
            int normal; // 正常下的颜色
            int hit;    // 选中下的颜色
        }

        // 尺寸
        // Ts 表示文字大小尺寸
        class Dimen {
            int height;         // 控件高度, 宽度为设备宽度,无需设置
            int width;          // 控件宽度
            int tS;             // 文字大小
            int paddingBottom;  // 控件距离底部的距离
        }

        // 资源
        // Tx 表示文字
        // DW 表示Drawable
        class Res {
            String normalTx; // 正常下的文字
            String hitTx;    // 选中下的文字
            Drawable normalDelDw; // 正常下的删除icon
            Drawable hitDelDw;    // 选中下的删除icon
        }
    }
}
